package org.psyduck.admin.menu.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.psyduck.admin.menu.dao.MenuDao;
import org.psyduck.admin.menu.entity.Menu;
import org.psyduck.admin.menu.entity.Route;
import org.psyduck.common.base.BaseService;
import org.psyduck.common.constant.Constants;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class MenuService extends BaseService<MenuDao, Menu> {

    @Transactional
    public void recursiveRemoveById(String id) {
        removeById(id);
        List<String> menus = getDao().selectMenusByPid(id);
        for (int i = 0; i < menus.size(); i++) {
            recursiveRemoveById(menus.get(i));
        }
    }
    
    public List<Route> getCurrentUserMenu(String userId) {
        List<Menu> menus;
        if (userId.equals(Constants.User.SUPER_ADMIN_ID)) {
            menus = getDao().selectList(new QueryWrapper<Menu>().eq(Constants.IS_DEL, Constants.NOT_DELETE).eq("is_show",1).orderByAsc("sort"));
        } else {
            menus = getDao().getCurrentUserMenu(userId);
        }
        LinkedHashMap<String, Route> nodes = new LinkedHashMap<>();
        for (int i = 0; i < menus.size(); i++) {
            Menu menu = menus.get(i);
            Route route = new Route();
            route.setId(menu.getId());
            route.setListConfig(menu.getListConfig());
            route.setFormConfig(menu.getFormConfig());
            route.setIsListConfig(menu.getIsListConfig());
            route.setName(menu.getName());
            route.setPid(menu.getPid());
            route.setIsShow(menu.getIsShow());
            route.setComponent(StrUtil.isBlank(menu.getUrl()) ? "Layout" : menu.getUrl() );
            route.setPath(route.getComponent().equals("Layout") ? "/" : route.getComponent());
            Route.Meta meta = new Route.Meta();
            meta.setTitle(menu.getName());
            route.setMeta(meta);
            route.setSort(menu.getSort());
            nodes.put(menus.get(i).getId(), route);
        }
        for (Route node : nodes.values()) {
            appendChild(node, nodes);
        }
        List<Route> treeNodes = new ArrayList<>();
        for (Route node : nodes.values()) {
            if (node.getPid().equals(Constants.Menu.FUNCTION_MENU_ID)) {
                treeNodes.add(node);
            }
            node.sort();
        }
        Collections.sort(treeNodes);
        return treeNodes;
    }

    private void appendChild(Route node, Map<String, Route> nodes) {
        if (nodes.containsKey(node.getPid())) {
            nodes.get(node.getPid()).setRedirect("noRedirect");
            nodes.get(node.getPid()).setComponent("Layout");
            nodes.get(node.getPid()).setAlwaysShow(true);
            nodes.get(node.getPid()).addChild(node);
        }
    }

    public List<Menu> getMenuTree() {
        List<Menu> menus = getDao().selectList(new QueryWrapper<Menu>().eq(Constants.IS_DEL, Constants.NOT_DELETE).orderByAsc("sort"));
        LinkedHashMap<String, Menu> nodes = new LinkedHashMap<>();
        for (int i = 0; i < menus.size(); i++) {
            nodes.put(menus.get(i).getId(), menus.get(i));
        }
        for (Menu node : nodes.values()) {
            menuTreeAppendChild(node, nodes);
        }
        List<Menu> treeNodes = new ArrayList<>();
        for (Menu node : nodes.values()) {
            if (node.getPid().equals(Constants.Menu.FUNCTION_MENU_ID)) {
                treeNodes.add(node);
            }
            node.sort();
        }
        Collections.sort(treeNodes);
        return treeNodes;
    }

    private void menuTreeAppendChild(Menu node, Map<String, Menu> nodes) {
        if (nodes.containsKey(node.getPid())) {
            nodes.get(node.getPid()).addChild(node);
        }
    }

}
